#!/usr/bin/env python3
"""
CTP API 完整安装脚本
自动完成所有安装步骤

使用方法:
    python install_complete.py target_directory
    
示例:
    python install_complete.py v6.7.11_20250617\\win64
"""

import os
import sys
import subprocess
import shutil
import argparse
from pathlib import Path

def read_depend_file():
    """读取 .depend 文件，返回项目类型字符串"""
    depend_file = Path(__file__).parent / ".depend"
    if not depend_file.exists():
        return "ctp"
    try:
        with open(depend_file, encoding="utf-8") as f:
            for line in f:
                line = line.strip()
                if line.startswith("PROJECT_TYPE="):
                    return line.split("=", 1)[1].strip()
    except Exception:
        pass
    return "ctp"

def copy_compiled_files(target_dir):
    """将编译好的文件拷贝到指定目录的 py[project_type] 子目录下
    
    Args:
        target_dir (str): 目标目录路径，相对于项目根目录
        
    此函数会从当前目录和 build 目录中找到所有编译文件，并将它们复制到 target_dir/py[project_type] 目录。
    后续会将 py[project_type] 目录安装到 site-packages。
    """
    
    # 获取项目类型
    project_type = read_depend_file()
    package_name = f"py{project_type}"
    
    # 获取项目根目录
    project_root = Path(__file__).parent.parent.resolve()
    
    # 构建目标路径
    target_path = project_root / target_dir
    if not target_path.exists():
        print(f"❌ 目标目录不存在: {target_path}")
        return False
    
    # 确保 target_dir/py[project_type] 目录存在且干净
    pyctp_dir = target_path / package_name
    if pyctp_dir.exists():
        # 如果目录已存在，删除整个目录
        shutil.rmtree(pyctp_dir)
        print(f"✅ 已清理旧目录: {pyctp_dir}")
    
    pyctp_dir.mkdir(parents=True, exist_ok=True)
    print(f"✅ 已创建目录: {pyctp_dir}")
    
    copied_files = []
    
    # 1. 从当前目录查找已编译的扩展模块（Windows: .pyd，Linux/macOS: .so）
    build_dir = Path(".")
    compiled_files_found = []
    
    if build_dir.exists():
        # 查找当前目录中的扩展文件
        patterns = ["*.pyd", "*.so"]
        for pattern in patterns:
            compiled_files_found.extend(list(build_dir.glob(pattern)))
        if not compiled_files_found:
            print(f"⚠️  在 {build_dir} 中未找到已编译的扩展文件(.pyd/.so)")
    else:
        print(f"⚠️  build目录不存在: {build_dir}")
    
    if compiled_files_found:
        for compiled_file in compiled_files_found:
            # 直接复制到包根目录，不保持子目录结构
            dst = pyctp_dir / compiled_file.name
            shutil.copy2(compiled_file, dst)
            copied_files.append(compiled_file.name)
            print(f"✅ 已复制 {compiled_file.name} 从 {compiled_file.parent} 到 {pyctp_dir}")
    else:
        print(f"⚠️  未找到任何扩展文件(.pyd/.so)")
    
    # 2. 从当前目录复制 .py 文件
    py_files = ["thosttraderapi.py", "thostmduserapi.py"]
    for py_file in py_files:
        src = Path(py_file)
        if src.exists():
            dst = pyctp_dir / py_file
            shutil.copy2(src, dst)
            copied_files.append(py_file)
            print(f"✅ 已复制 {py_file} 到 {pyctp_dir}")
        else:
            print(f"⚠️  未找到 {py_file}")
    
    # 3. 从当前目录复制运行时库（Windows: .dll，Linux/macOS: .so）
    # 读取.depend文件获取实际存在的库文件
    depend_libs = []
    depend_file = Path(".depend")
    if depend_file.exists():
        with open(depend_file, 'r', encoding='utf-8') as f:
            for line in f:
                line = line.strip()
                if line and not line.startswith('#'):
                    if line.endswith('.dll') or line.endswith('.so'):
                        lib_name = line
                        if Path(lib_name).exists():
                            depend_libs.append(lib_name)
    
    # 如果没有从.depend文件找到，使用默认的库文件列表（按平台）
    if not depend_libs:
        if sys.platform == 'win32':
            possible_libs = [
                "thostmduserapi_se.dll", "thosttraderapi_se.dll",
                "thostmduserapi.dll", "thosttraderapi.dll"
            ]
        else:
            possible_libs = [
                "thostmduserapi_se.so", "thosttraderapi_se.so",
                "libthostmduserapi_se.so", "libthosttraderapi_se.so",
                "thostmduserapi.so", "thosttraderapi.so",
                "libthostmduserapi.so", "libthosttraderapi.so"
            ]
        depend_libs = [lib for lib in possible_libs if Path(lib).exists()]
    
    if depend_libs:
        for lib_file in depend_libs:
            src = Path(lib_file)
            dst = pyctp_dir / lib_file
            shutil.copy2(src, dst)
            copied_files.append(lib_file)
            print(f"✅ 已复制 {lib_file} 到 {pyctp_dir}")
    else:
        print(f"⚠️  未找到任何运行时库(.dll/.so)")
    
    # 4. 创建 __init__.py 文件
    init_content = """# 自动生成的包初始化
# CTP API Python接口

import os
import sys
from pathlib import Path

_package_dir = Path(__file__).parent

if sys.platform == 'win32':
    if hasattr(os, 'add_dll_directory'):
        try:
            os.add_dll_directory(str(_package_dir))
        except (OSError, AttributeError):
            os.environ['PATH'] = str(_package_dir) + os.pathsep + os.environ.get('PATH', '')
    else:
        os.environ['PATH'] = str(_package_dir) + os.pathsep + os.environ.get('PATH', '')
elif sys.platform.startswith('linux'):
    os.environ['LD_LIBRARY_PATH'] = str(_package_dir) + os.pathsep + os.environ.get('LD_LIBRARY_PATH', '')
elif sys.platform == 'darwin':
    os.environ['DYLD_LIBRARY_PATH'] = str(_package_dir) + os.pathsep + os.environ.get('DYLD_LIBRARY_PATH', '')

# 导入模块
from .thosttraderapi import *
from .thostmduserapi import *

__all__ = ['thosttraderapi', 'thostmduserapi']
"""
    init_file = pyctp_dir / "__init__.py"
    init_file.write_text(init_content, encoding="utf-8")
    copied_files.append("__init__.py")
    print(f"✅ 已创建 {init_file}")
    
    # 检查复制结果
    if not copied_files:
        print("❌ 未复制任何文件")
        return False
    
    print(f"\n✅ 总共复制了 {len(copied_files)} 个文件到 {pyctp_dir}:")
    for file in copied_files:
        print(f"  - {file}")
    
    return True

def create_pyctp_package(pyctp_dir):
    """将 py[project_type] 目录安装到 site-packages
    
    Args:
        pyctp_dir (Path): py[project_type] 目录的路径
    """
    try:
        # 获取项目类型
        project_type = read_depend_file()
        package_name = f"py{project_type}"
        
        # 获取用户级site-packages目录
        import site
        user_site = site.getusersitepackages()
        
        # 确保用户级site-packages目录存在
        os.makedirs(user_site, exist_ok=True)
        
        # 目标py[project_type]目录
        target_pyctp = Path(user_site) / package_name
        
        # 如果目标目录已存在，先删除
        if target_pyctp.exists():
            shutil.rmtree(target_pyctp)
            print(f"✅ 已删除旧的pyctp目录: {target_pyctp}")
        
        # 复制pyctp目录到site-packages
        shutil.copytree(pyctp_dir, target_pyctp)
        print(f"✅ 已将pyctp目录复制到: {target_pyctp}")
        
        # 列出复制的文件
        copied_files = []
        for file in target_pyctp.glob("*"):
            if file.is_file():
                copied_files.append(file.name)
        
        print(f"\n✅ 总共复制了 {len(copied_files)} 个文件到 site-packages:")
        for file in copied_files:
            print(f"  - {file}")
        
        return True
        
    except Exception as e:
        print(f"❌ 创建pyctp包失败: {e}")
        return False





def verify_installation():
    """验证安装是否成功"""
    try:
        # 获取项目类型
        project_type = read_depend_file()
        package_name = f"py{project_type}"
        
        print(f"正在验证 {package_name} 包安装...")
        
        # 动态导入对应的包
        package = __import__(package_name)
        print(f"✅ {package_name} 包导入成功！")
        
        # 测试直接导入模块（避免循环导入）
        try:
            thosttraderapi = __import__(f"{package_name}.thosttraderapi", fromlist=[''])
            print("✅ thosttraderapi模块导入成功！")
        except ImportError as e:
            print(f"⚠️  thosttraderapi导入警告: {e}")
            # 尝试直接导入底层模块
            _thosttraderapi = __import__(f"{package_name}._thosttraderapi", fromlist=[''])
            print("✅ _thosttraderapi模块导入成功！")
        
        try:
            thostmduserapi = __import__(f"{package_name}.thostmduserapi", fromlist=[''])
            print("✅ thostmduserapi模块导入成功！")
        except ImportError as e:
            print(f"⚠️  thostmduserapi导入警告: {e}")
            # 尝试直接导入底层模块
            _thostmduserapi = __import__(f"{package_name}._thostmduserapi", fromlist=[''])
            print("✅ _thostmduserapi模块导入成功！")
        
        # 获取安装路径
        import site
        site_packages = Path(site.getusersitepackages())
        pyctp_dir = site_packages / package_name
        
        if pyctp_dir.exists():
            print(f"✅ {package_name}目录已安装: {pyctp_dir}")
            print("✅ 包含文件:")
            for file in pyctp_dir.glob("*"):
                if file.is_file():
                    print(f"  - {file.name} ({file.stat().st_size:,} bytes)")
        
        # 验证 base 模块（如果存在）
        try:
            base_module = __import__(f"{package_name}.base", fromlist=[''])
            print("✅ base 模块导入成功")
        except ImportError:
            print("⚠️  base 模块导入失败（可能不存在，这是可选的）")
        
        return True
        
    except ImportError as e:
        print(f"❌ 导入失败: {e}")
        print("💡 提示：请确保所有.pyd文件已正确复制到目录")
        return False
    except Exception as e:
        print(f"❌ 验证过程出错: {e}")
        return False

def copy_base_to_pyctp(pyctp_dir: Path) -> bool:
    """将项目根目录下的 base 目录复制到指定的 py[project_type] 目录内
    - 目标路径: py[project_type]/base
    - 复制前会清理旧的 base 目录
    - 忽略 __pycache__ 和 .pyc 文件
    """
    try:
        project_root = Path(__file__).parent.parent.resolve()
        src_base = project_root / "base"
        dst_base = pyctp_dir / "base"

        if not src_base.exists():
            print(f"❌ base 目录不存在: {src_base}")
            return False

        # 如果目标存在，先删除
        if dst_base.exists():
            shutil.rmtree(dst_base)
            print(f"✅ 已清理旧 base 目录: {dst_base}")

        shutil.copytree(
            src_base,
            dst_base,
            ignore=shutil.ignore_patterns("__pycache__", "*.pyc", ".DS_Store")
        )
        print(f"✅ 已复制 base 目录到: {dst_base}")
        return True
    except Exception as e:
        print(f"❌ 复制 base 目录失败: {e}")
        return False

def main():
    """主函数"""
    
    # 获取项目类型
    project_type = read_depend_file()
    package_name = f"py{project_type}"
    target_dir = package_name   # 使用项目类型作为目录名
    
    # 获取包目录路径
    project_root = Path(__file__).parent.resolve()
    pyctp_dir = project_root / target_dir    
    print("=== CTP API 完整安装工具 ===\n")
    print(f"项目类型: {project_type}")
    print(f"待安装的包目录: {pyctp_dir}")
    
    # 步骤1: 复制 base 目录到包目录（确保安装时包含 base）
    print(f"\n步骤1: 复制 base 目录到 {package_name}...")
    if not copy_base_to_pyctp(pyctp_dir):
        print("❌ 复制 base 目录失败！")
        sys.exit(1)
    
    # 步骤2: 创建包并安装到site-packages（如果未跳过）
    print(f"\n步骤2: 创建{package_name}包并安装到site-packages...")
    if not create_pyctp_package(pyctp_dir):
        print("❌ 安装失败！")
        sys.exit(1)
    
    # 步骤3: 验证安装（如果未跳过且未跳过安装）
    print(f"\n步骤3: 验证{package_name}安装...")
    if not verify_installation():
        print("❌ 验证失败！")
        sys.exit(1)
    
    print("\n🎉 编译和打包完成！")
    print("\n使用方法:")
    print(f"  import {package_name}")
    print(f"  from {package_name} import thosttraderapi  # 交易API")
    print(f"  from {package_name} import thostmduserapi  # 行情API")
    print(f"  from {package_name}.base import TraderApi, MdApi  # 项目内 base 模块（示例）")
    
    return 0

if __name__ == "__main__":
    sys.exit(main())